package net.jumpengine.ui;

import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
import net.jumpengine.M;
import net.jumpengine.bean.ImageBase;
/**
  * 九宫格就是用两条竖线(x1,x2)和两条横线(y1,y2),将图像分为九块, <br />
  * 然后用这九块拼出不小于原始图像的任意大小的图像.
 * <br /><br />
 * <b>作者:&nbsp;</b>张天文 <br />
 * <b>日期:&nbsp;</b>2020年8月14日 下午6:26:49<br />
 * @date
 */
public class NineBox extends ImageBase {
	protected int x1,x2,y1,y2;
	//九宫格中心格的宽度和高度
	private int oneW,oneH;
	//中心格临时宽度和高度,用于判断剩余尺寸不够一中心格时得到剩下的尺寸.
	private int tw,th;
	//图像的宽度和高度
	private int iw,ih;
	//九宫分割线x2,y2在绘制大小中交点的坐标
	private int sx2,sy2;
	//九宫格绘制时中心格的宽度和高度
	private int cWidth,cHeight;
	private int countX=0,countY=0;
	private int minWidth,minHeight;
	private boolean change=true;
	private boolean first=true;
	
	/**
	  * 九宫格构造函数,默认层级
	 * @param image 可以分为九块,并且上下左右边和中间格都是能重复的这样一幅图像.
	 * @param x1 竖线1
	 * @param x2 竖线2,比x1大
	 * @param y1 横线1
	 * @param y2 横线2,比y1大
	 * @param x x坐标
	 * @param y y坐标
	 * @param width 绘制的宽度
	 * @param height 绘制的高度
	 */
	public NineBox (Image image,int x1,int x2,int y1,int y2,int x,int y,int width,int height) {
		this(image, x1, x2, y1, y2, x2, y, width, height,0);
	}
	
	/**
	  * 九宫格构造函数,自定义层级
	 * @param image 可以分为九块,并且上下左右边和中间格都是能重复的这样一幅图像.
	 * @param x1 竖线1
	 * @param x2 竖线2,比x1大
	 * @param y1 横线1
	 * @param y2 横线2,比y1大
	 * @param x x坐标
	 * @param y y坐标
	 * @param width 绘制的宽度
	 * @param height 绘制的高度
	 * @param index 层级
	 */
	public NineBox (Image image,int x1,int x2,int y1,int y2,int x,int y,int width,int height,int index) {
		super(x, y, width, height,index, image);
		this.x1=x1;
		this.x2=x2;
		this.y1=y1;
		this.y2=y2;
		this.iw=(int) image.getWidth();
		this.ih=(int) image.getHeight();
		minWidth=iw-x2+x1;
		minHeight=ih-y1+y1;
	}
	
	@Override
	public void draw(GraphicsContext g) {
		if(change) {
			oneW=x2-x1;
			oneH=y2-y1;
			cWidth=width-x1-iw+x2;
			cHeight=height-y1-ih+y2;
			sx2=x+width-iw+x2;
			sy2=y+height-ih+y2;
			countX= (int)Math.ceil(cWidth*1.0/oneW);
			countY= (int)Math.ceil(cHeight*1.0/oneH);
			minWidth=iw-oneW;
			minHeight=ih-oneH;
			change=false;
		}
		
		for(int i=0;i<countX;i++) {
			for(int j=0;j<countY;j++) {
				tw=(cWidth-i*oneW<oneW)?cWidth-i*oneW:oneW;
				th=(cHeight-j*oneH<oneH)?cHeight-j*oneH:oneH;
				g.drawImage(image, x1, y1,tw, th, x+x1+i*oneW, y+y1+j*oneH, tw, th);
			}
		}
		
		g.drawImage(image, 0, 0, x1, y1, x, y, x1, y1); //左上
		g.drawImage(image, 0,y2, x1,ih-y2,x, sy2, x1, ih-y2); //左下
		
		for(int i=0;i<countX;i++) {
			tw=(cWidth-i*oneW<oneW)?cWidth-i*oneW:oneW;
			g.drawImage(image, x1,0, oneW, y1, x+x1+i*oneW, y, tw, y1); //上边
			g.drawImage(image, x1,y2, oneW, ih-y2, x+x1+i*oneW, sy2, tw, ih-y2); //下边
		}
		
		g.drawImage(image, x2, 0, iw-x2, y1, sx2, y, iw-x2, y1); //右上
		g.drawImage(image, x2, y2, iw-x2, ih-y2, sx2, sy2, iw-x2, ih-y2); //右下
		
		for(int j=0;j<countY;j++) {
			th=(cHeight-j*oneH<oneH)?cHeight-j*oneH:oneH;
			g.drawImage(image, 0,y1, x1, th, x, y+y1+j*oneH, x1, th); //左边
			g.drawImage(image, x2,y1, iw-x2, th, sx2, y+y1+j*oneH, iw-x2, th); //右边
		}

	}

	public int getX1() {
		return x1;
	}

	public void setX1(int x1) {
		this.x1 = x1;
		change=true;
	}

	public int getX2() {
		return x2;
	}

	public void setX2(int x2) {
		this.x2 = x2;
		change=true;
	}

	public int getY1() {
		return y1;
	}

	public void setY1(int y1) {
		this.y1 = y1;
		change=true;
	}

	public int getY2() {
		return y2;
	}

	public void setY2(int y2) {
		this.y2 = y2;
		change=true;
	}
	
	@Override
	public void setSize(int width, int height) {
		super.setSize(width, height);
		change=true;
	}
	
	@Override
	public void setWidth(int width) {
		if(width>=minWidth) {
			this.width=width;
			change=true;
		}else {
			M.l().info(this.getClass(), "width(",width,")小于minWidth(",minWidth,")");
		}
	}
	@Override
	public void setHeight(int height) {
		if(height>=minHeight) {
			this.height=height;
			change=true;
		}else {
			M.l().info(this.getClass(), "height(",height,")小于minHeight(",minHeight,")");
		}
	}

	public int getMinWidth() {
		return minWidth;
	}

	public int getMinHeight() {
		return minHeight;
	}

	public boolean isFirst() {
		return first;
	}

	public void setFirst(boolean first) {
		this.first = first;
	}
}
